/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_components/zhiqim_manager.htm
 *
 * Zhiqim Manager is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package net.redxyz.repost.service.dao;

import java.sql.SQLException;
import java.util.LinkedHashMap;
import java.util.List;

import org.zhiqim.kernel.config.ItemType;
import org.zhiqim.kernel.constants.SignConstants;
import org.zhiqim.kernel.util.DateTimes;
import org.zhiqim.kernel.util.Ints;
import org.zhiqim.kernel.util.Longs;
import org.zhiqim.kernel.util.Validates;
import org.zhiqim.manager.ZmrConstants;
import org.zhiqim.orm.ORM;
import org.zhiqim.orm.ORMException;
import org.zhiqim.orm.ORMServer;
import org.zhiqim.orm.dbo.Selector;
import org.zhiqim.orm.dbo.Updater;

import net.redxyz.top.dbo.sys.SysParam;

/**
 * 参数访问对象
 *
 * @version v1.0.0 @author zouzhigang 2015-5-28 新建与整理
 * @version v1.4.1 @author zouzhigang 2018-5-3 由SysParamCache改为SysParamDao
 * @version v1.6.0 @author zouzhigang 2021-4-20 把ZMR自带的优先放最前，使ZhiqimConsole/ZhiqimAdmin/ZhiqimManager尽可能适配
 */
public class SysParamDao implements ZmrConstants, SignConstants
{
    public static final String ZMR_THEME_00_DEFAULT         = "00_default";
    public static final String ZMR_THEME_01_CLASSIC         = "01_classic";
    public static final String ZMR_THEME_02_CONCISE         = "02_concise";
    public static final String ZMR_THEME_03_ELEGANT         = "03_elegant";
    public static final String ZMR_THEME_04_FRESH           = "04_fresh";
    public static final String ZMR_THEME_05_FLATWISE        = "05_flatwise";
    /** 获取工程参数中的缺省域 */
    public static String getDefaultDomain() throws ORMException, SQLException
    {
        return getString("project.param", "defaultDomain", "001");
    }
    
    /** 获取工程参数中缺省的JDP实例名 */
    public static String getDefaultJdpName()
    {
        try
        {
            return getString("project.param", "defaultJdpName");
        }
        catch (ORMException | SQLException e)
        {
            return null;
        }
    }
    
    /** 获取最后用户订购关系同步时间 */
    public static String getLastOrderSyncTime() throws ORMException, SQLException
    {
        return getString("timer.param", "lastOrderSyncTime", DateTimes.getPreviousDateString() + " 00:00:00");
    }

    /** 获取最后统计用户订购日期 */
    public static String getLastOrderStatDate() throws ORMException, SQLException
    {
        return getString("timer.param", "lastOrderStatDate", DateTimes.getFirstMonthDay());
    }

    /** 获取上架不支持的类目 */
    public static String getRepostNoCids() throws ORMException, SQLException
    {
        return getString("timer.param", "repostNoCids", "50004958,150401,150402,150406,50011814,99");
    }

    /** 根据版本取广告 */
    public static String getPortalAds(int versionNo) throws ORMException, SQLException
    {
        if (versionNo <= 1)
            return getString("portal.ads", "1");
        else if (versionNo > 1 && versionNo < 8)
            return getString("portal.ads", "5");
        else
            return getString("portal.ads", "8");
    }

    /*******************************************************************************/
    // 杨彩印刷项目
    /*******************************************************************************/
    public static String getYangCaiSellerNick() throws ORMException, SQLException
    {
        return getString("project.param", "yangCaiSellerNick", "yawiiwen");
    }

    /*******************************************************************************/
    // 弹出广告图
    /**
     * @throws SQLException 
     * @throws ORMException *****************************************************************************/

    public static boolean isPortalPopup() throws ORMException, SQLException
    {
        return isTrue("portal.popup", "is");
    }

    public static int getPortalPopupVersion() throws ORMException, SQLException
    {
        return getInt("portal.popup", "version", 10);
    }

    public static String getPortalPopupOrderDate() throws ORMException, SQLException
    {
        return getString("portal.popup", "orderDate");
    }

    public static String getPortalPopupTitle() throws ORMException, SQLException
    {
        return getString("portal.popup", "title");
    }

    public static String getPortalPopupUrl() throws ORMException, SQLException
    {
        return getString("portal.popup", "url");
    }

    public static String getPortalPopupTarget() throws ORMException, SQLException
    {
        return getString("portal.popup", "target");
    }

    public static String getPortalPopupImg() throws ORMException, SQLException
    {
        return getString("portal.popup", "img");
    }

    public static String getPortalPopupWidth() throws ORMException, SQLException
    {
        return getString("portal.popup", "width");
    }

    public static String getPortalPopupHeight() throws ORMException, SQLException
    {
        return getString("portal.popup", "height");
    }

    /*******************************************************************************/
    // 弹出顶尾部通知
    /*******************************************************************************/

    public static boolean isPortalNotice() throws ORMException, SQLException
    {
        return isTrue("portal.notice", "is");
    }

    public static int getPortalNoticeVersion() throws ORMException, SQLException
    {
        return getInt("portal.notice", "version");
    }

    public static String getPortalNoticeTitle() throws ORMException, SQLException
    {
        return getString("portal.notice", "title");
    }

    public static String getPortalNoticeUrl() throws ORMException, SQLException
    {
        return getString("portal.notice", "url");
    }

    public static String getPortalNoticeTarget() throws ORMException, SQLException
    {
        return getString("portal.notice", "target");
    }

    public static boolean isPortalNoticeAllowClose() throws ORMException, SQLException
    {
        return isTrue("portal.notice", "allowClose");
    }

    public static String getPortalNoticeLineNum() throws ORMException, SQLException
    {
        return getString("portal.notice", "lineNum");
    }
    
    /*************************************************************************************************/
    //获取标准ZMR自带的参数
    /*************************************************************************************************/
    
    /** 获取首页主题风格 */
    public static String getThemeIndex() throws ORMException, SQLException
    {
        return getString(ZMR_NAME, ZMR_THEME_INDEX, ZMR_THEME_00_DEFAULT);
    }
    
    /** 获取主页主题风格 */
    public static String getThemeMain() throws ORMException, SQLException
    {
        return getString(ZMR_NAME, ZMR_THEME_MAIN, ZMR_THEME_00_DEFAULT);
    }
    
    public static boolean isThemeFrame() throws ORMException, SQLException
    {
        return isTrue(ZMR_NAME, ZMR_THEME_FRAME, _FALSE_);
    }
    
    /** 是否有管理登录页 */
    public static boolean hasManageLogin() throws ORMException, SQLException
    {
        return isTrue(ZMR_NAME, ZMR_HAS_MANAGE_LOGIN);
    }
    
    /** 是否有验证码 */
    public static boolean hasVerificationCode() throws ORMException, SQLException
    {
        return isTrue(ZMR_NAME, ZMR_HAS_VERIFICATION_CODE);
    }
    
    /** 是否记住用户名 */
    public static boolean hasRememberCode() throws ORMException, SQLException
    {
        return isTrue(ZMR_NAME, ZMR_HAS_REMEMBER_CODE);
    }
    
    /** 是否记住密码 */
    public static boolean hasRememberPass() throws ORMException, SQLException
    {
        return isTrue(ZMR_NAME, ZMR_HAS_REMEMBER_PASS);
    }
    
    /** 获取主页地址 */
    public static String getMainUrl() throws ORMException, SQLException
    {
        return getString(ZMR_NAME, ZMR_MAIN_URL, ZMR_MAIN_URL_DEFAULT);
    }
    
    /** 获取主页首页地址 */
    public static String getMainIndexUrl() throws ORMException, SQLException
    {
        return isThemeFrame()?ZMR_MAIN_URL_WELCOME:ZMR_MAIN_URL_DEFAULT;
    }

    /** 获取保留操作日志天数 */
    public static int getRemainLogDay() throws ORMException, SQLException
    {
        return getInt(ZMR_NAME, ZMR_REMAIN_LOG_DAY, 7);
    }
    
    /** 是否使用CDN路径 */
    public static boolean hasCdnPath() throws ORMException, SQLException
    {
        return !Validates.isEmptyBlank(getString(ZMR_NAME, ZMR_CDN_PATH));
    }
    
    /** 获取CDN路径 */
    public static String getCdnPath() throws ORMException, SQLException
    {
        return getString(ZMR_NAME, ZMR_CDN_PATH);
    }
    
    /** 获取公钥 */
    public static String getPublicKey() throws ORMException, SQLException
    {
        return getString(ZMR_NAME, ZMR_PUBLIC_KEY);
    }
    
    /** 获取私钥 */
    public static String getPrivateKey() throws ORMException, SQLException
    {
        return getString(ZMR_NAME, ZMR_PRIVATE_KEY);
    }
    
    /** 是否取操作员继承的所有部门权限 */
    public static boolean isOperatorDeptAllRule() throws ORMException, SQLException
    {
        return isTrue(ZMR_NAME, ZMR_OPERATOR_DEPT_ALL_RULE);
    }
    
    /*************************************************************************************************/
    //更新标准ZMR自带的参数
    /*************************************************************************************************/
    
    /** 更新首页主题风格 */
    public static void doUpdateThemeIndex(String theme) throws ORMException, SQLException
    {
        doUpdate(ZMR_NAME, ZMR_THEME_INDEX, theme);
    }
    
    /** 更新主页主题风格 */
    public static void doUpdateThemeMain(String theme) throws ORMException, SQLException
    {
        doUpdate(ZMR_NAME, ZMR_THEME_MAIN, theme);
    }
    
    /** 更新是否有管理登录页 */
    public static void doUpdateManageLogin(boolean value) throws ORMException, SQLException
    {
        doUpdate(ZMR_NAME, ZMR_HAS_MANAGE_LOGIN, value);
    }
    
    /** 更新记住用户名 */
    public static void doUpdateRememberCode(boolean value) throws ORMException, SQLException
    {
        doUpdate(ZMR_NAME, ZMR_HAS_REMEMBER_CODE, value?_TRUE_:_FALSE_);
    }
    
    /** 更新需要验证码 */
    public static void doUpdateVerificationCode(boolean value) throws ORMException, SQLException
    {
        doUpdate(ZMR_NAME, ZMR_HAS_VERIFICATION_CODE, value);
    }
    
    /*************************************************************************************************/
    //默认为第一个数据库初始化参数
    /*************************************************************************************************/
    
    /** 检查数据不存在时新建参数对象，默认值和验证为空，允许修改 */
    public static void addParamIfNotExists(String paramGroup, String paramKey, int paramSeq, String paramDesc) throws Exception
    {
        addParamIfNotExists(paramGroup, paramKey, null, paramSeq, ItemType.PUBLIC, null, paramDesc);
    }
    
    /** 检查数据不存在时新建参数对象，默认验证为空 */
    public static void addParamIfNotExists(String paramGroup, String paramKey, String paramValue, int paramSeq, ItemType paramType, String paramDesc) throws Exception
    {
        addParamIfNotExists(paramGroup, paramKey, paramValue, paramSeq, paramType, null, paramDesc);
    }
    
    /** 检查数据不存在时新建参数对象，全7个字段 */
    public static void addParamIfNotExists(String paramGroup, String paramKey, String paramValue, int paramSeq, ItemType paramType, String paramValidate, String paramDesc) throws Exception
    {
        if (ORM.table().count(SysParam.class, paramGroup, paramKey) == 0)
        {
            replaceParam(paramGroup, paramKey, paramValue, paramSeq, paramType, paramValidate, paramDesc);
        }
    }
    
    /** 新建或替换参数对象，默认验证为空 */
    public static void replaceParam(String paramGroup, String paramKey, String paramValue, int paramSeq, ItemType paramType, String paramDesc) throws Exception
    {
        replaceParam(paramGroup, paramKey, paramValue, paramSeq, paramType, null, paramDesc);
    }
    
    /** 新建或替换参数对象，全7个字段 */
    public static void replaceParam(String paramGroup, String paramKey, String paramValue, int paramSeq, ItemType paramType, String paramValidate, String paramDesc) throws Exception
    {
        SysParam param = new SysParam();
        param.setParamGroup(paramGroup);
        param.setParamKey(paramKey);
        param.setParamValue(paramValue);
        param.setParamSeq(paramSeq);
        param.setParamType(ItemType.toString(paramType));
        param.setParamValidate(paramValidate);
        param.setParamDesc(paramDesc);

        ORM.table().replace(param);
    }
    
    /*************************************************************************************************/
    //默认为第一个数据库配置的获取参数方法
    /*************************************************************************************************/
    
    /** 判断是否存在参数组 */
    public static boolean hasGroup(String paramGroup) throws ORMException, SQLException
    {
        return ORM.table().count(SysParam.class, new Selector("paramGroup", paramGroup)) > 0;
    }
    
    /** 判断是否存在参数 */
    public static boolean hasParam(String paramGroup, String paramKey) throws ORMException, SQLException
    {
        return ORM.table().count(SysParam.class, paramGroup, paramKey) > 0;
    }
    
    /** 获取参数组表 */
    public static LinkedHashMap<String, LinkedHashMap<String, SysParam>> getGroupMap() throws ORMException, SQLException
    {
        LinkedHashMap<String, LinkedHashMap<String, SysParam>> groupMap = new LinkedHashMap<>();
        
        List<SysParam> paramList = ORM.table().list(SysParam.class, new Selector().addMustNotEqual("paramType", "private").addOrderbyAsc("paramGroup,paramSeq"));
        for (SysParam param : paramList)
        {
            LinkedHashMap<String, SysParam> paramMap = groupMap.get(param.getParamGroup());
            if (paramMap == null)
            {
                paramMap = new LinkedHashMap<String, SysParam>();
                groupMap.put(param.getParamGroup(), paramMap);
            }
            
            paramMap.put(param.getParamKey(), param);
        }
        return groupMap;
    }
    
    /** 获取参数（获取缓存拷贝数据） */
    public static SysParam getParam(String paramGroup, String paramKey) throws ORMException, SQLException
    {
        return ORM.table().item(SysParam.class, paramGroup, paramKey);
    }
    
    /** 获取参数（获取缓存原始数据） */
    public static SysParam getParamCacheRaw(String paramGroup, String paramKey) throws ORMException, SQLException
    {
        return ORM.table().cacheItemRaw(SysParam.class, paramGroup, paramKey);
    }
    
    /** 获取字符串数据（如果有缓存，取原始缓存，否则取数据库） */
    public static String getString(String paramGroup, String paramKey) throws ORMException, SQLException
    {
        ORMServer server = ORM.server();
        
        SysParam param = null;
        if (server.isCache(SysParam.class))
            param = server.table().cacheItemRaw(SysParam.class, paramGroup, paramKey);
        else
            param = server.table().item(SysParam.class, paramGroup, paramKey);
        
        return (param == null)?null:param.getParamValue();
    }
    
    /** 获取字符串数据，为null取缺省值 */
    public static String getString(String paramGroup, String paramKey, String defaultValue) throws ORMException, SQLException
    {
        String value = getString(paramGroup, paramKey);
        return (Validates.isEmptyBlank(value))?defaultValue:value;
    }
    
    /** 获取整型数据 */
    public static int getInt(String paramGroup, String paramKey) throws ORMException, SQLException
    {
        return getInt(paramGroup, paramKey, -1);
    }
    
    /** 获取整型数据，为null取缺省值 */
    public static int getInt(String paramGroup, String paramKey, int defaultValue) throws ORMException, SQLException
    {
        return Ints.toInt(getString(paramGroup, paramKey), defaultValue);
    }
    
    /** 获取长整型数据 */
    public static long getLong(String paramGroup, String paramKey) throws ORMException, SQLException
    {
        return getLong(paramGroup, paramKey, -1);
    }
    
    /** 获取整型数据，为null取缺省值 */
    public static long getLong(String paramGroup, String paramKey, int defaultValue) throws ORMException, SQLException
    {
        return Longs.toLong(getString(paramGroup, paramKey), defaultValue);
    }
    
    /** 判断是否为真 */
    public static boolean isTrue(String paramGroup, String paramKey) throws ORMException, SQLException
    {
        return _TRUE_.equals(getString(paramGroup, paramKey));
    }
    
    /** 判断是否为真，为null取缺省值 */
    public static boolean isTrue(String paramGroup, String paramKey, String defaultValue) throws ORMException, SQLException
    {
        return _TRUE_.equals(getString(paramGroup, paramKey, defaultValue));
    }

    /*************************************************************************************************/
    //默认为第一个数据库配置的更新和刷新参数
    /*************************************************************************************************/
    
    /** 更新缓存值 */
    public static boolean doUpdate(String paramGroup, String paramKey, int paramValue) throws ORMException, SQLException
    {
        return doUpdate(paramGroup, paramKey, String.valueOf(paramValue));
    }
    
    /** 更新缓存值 */
    public static boolean doUpdate(String paramGroup, String paramKey, long paramValue) throws ORMException, SQLException
    {
        return doUpdate(paramGroup, paramKey, String.valueOf(paramValue));
    }
    
    /** 更新缓存值 */
    public static boolean doUpdate(String paramGroup, String paramKey, boolean paramValue) throws ORMException, SQLException
    {
        return doUpdate(paramGroup, paramKey, String.valueOf(paramValue));
    }
    
    /** 更新缓存值 */
    public static boolean doUpdate(String paramGroup, String paramKey, String paramValue) throws ORMException, SQLException
    {
        //更新到数据库
        Updater updater = new Updater();
        updater.addMust("paramGroup", paramGroup);
        updater.addMust("paramKey", paramKey);
        updater.addField("paramValue", paramValue);
        return ORM.table().update(SysParam.class, updater) > 0;
    }
}